/**
 * 
 */
package org.ranch.web.controllers;

import java.util.List;

import org.ranch.api.security.PermissionConstants;
import org.ranch.api.service.UserService;
import org.ranch.model.Role;
import org.ranch.model.exception.RanchOperationFailedException;
import org.ranch.model.exception.RanchValidationException;
import org.ranch.web.WebConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Jmpango
 * 
 */
@Controller
@RequestMapping("role")
public class RolesController {

    @Autowired
    private UserService userService;

    /**
     * Handler to view roles and permissions in the system
     * 
     * @param pageNo
     * @param model
     * @return
     */
    @Secured(PermissionConstants.PERM_ADMIN)
    @RequestMapping(method = RequestMethod.GET, params = { "action=view", "item=roles" })
    public ModelAndView viewRoleHandler(
	    @RequestParam(value = "pageNo", required = false) Integer pageNo, ModelMap model) {

	if (pageNo == null || (pageNo != null && pageNo <= 0)) {
	    pageNo = 0;
	}

	List<Role> roles = userService.getRolesByPage(pageNo);
	model.put("roles", roles);
	return new ModelAndView("roleView", model);
    }

    /**
     * handler method to handle the request for adding a new role
     * 
     * @return
     */
    @Secured(PermissionConstants.PERM_ADMIN)
    @RequestMapping(method = RequestMethod.GET, params = { "action=add",
			"item=role" })
    public ModelAndView viewAddRoleHandler(ModelMap model) {
	prepareRoleFormModel(model);
	model.put("role", new Role());

	return new ModelAndView("addRole", model);
    }

    private void prepareRoleFormModel(ModelMap model) {
	model.put("permissions", userService.getPermissions());
    }

    /**
     * handler method to handle the request to save a role
     * 
     * @param role
     * @param model
     * @return
     */
    @Secured(PermissionConstants.PERM_ADMIN)
    @RequestMapping(method = RequestMethod.POST, params = { "action=save",
			"item=role" })
    public ModelAndView saveRoleHandler(@ModelAttribute("role") Role role,
			ModelMap model) {
	if (role != null) {
	    try {
		userService.saveRole(role);
		model.put(WebConstants.MODEL_ATTRIBUTE_SYSTEM_MESSAGE,
						"role saved successfully");
	    } catch (RanchValidationException ex) {
		model.put(WebConstants.MODEL_ATTRIBUTE_ERROR_MESSAGE,
						ex.getMessage());
	    }
	}

	return viewRoleHandler(1, model);
    }

    /**
     * handler method to handle the delete request for a role
     * 
     * @param roleId
     * @param model
     * @return
     */
    @Secured(PermissionConstants.PERM_ADMIN)
    @RequestMapping(method = RequestMethod.GET, params = { "action=delete",
			"item=role" })
    public ModelAndView deleteRoleHandler(@RequestParam("id") String roleId,
			ModelMap model) {
	Role role = userService.getRoleById(roleId);
	if (role != null) {
	    try {
		userService.deleteRole(role);
		model.put(WebConstants.MODEL_ATTRIBUTE_SYSTEM_MESSAGE,
						"role >> " + role.getName()
							+ " deleted successfully");
	    } catch (RanchOperationFailedException e) {
		model.put(WebConstants.MODEL_ATTRIBUTE_ERROR_MESSAGE,
						e.getMessage());
	    }
	} else {
	    model.put(
		    WebConstants.MODEL_ATTRIBUTE_ERROR_MESSAGE,
					"the role id supplied does not belong to a valid role in the system");
	}
	return viewRoleHandler(null, model);
    }

    /**
     * handler method to handle the request for editing a role
     * 
     * @param roleId
     * @param model
     * @return
     */
    @Secured(PermissionConstants.PERM_ADMIN)
    @RequestMapping(method = RequestMethod.GET, params = { "action=edit",
			"item=role" })
    public ModelAndView viewEditRoleHandler(@RequestParam("id") String roleId,
			ModelMap model) {
	Role role = userService.getRoleById(roleId);
	if (role != null) {
	    prepareRoleFormModel(model);
	    model.put("role", role);

	    return new ModelAndView("addRole", model);
	} else {
	    model.put(WebConstants.MODEL_ATTRIBUTE_ERROR_MESSAGE,
					"role with the specified id does not exist");
	    return viewRoleHandler(null, model);
	}
    }

}
